package sunwin.yois.web.controller;

import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import jodd.util.BCrypt;
import net.sf.json.JSONObject;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import sunwin.yois.web.common.R;
import sunwin.yois.web.common.YoisAjaxAnswer;
import sunwin.yois.web.common.YoisControllerDefaultData;
import sunwin.yoms.comm.YomsException;
import sunwin.yoms.comm.YomsHelper;
import sunwin.yoms.comm.YomsPage;
import sunwin.yoms.domain.person.UserDomain;
import sunwin.yoms.domain.resource.StadiumDomain;
import sunwin.yoms.service.person.UserService;
import sunwin.yoms.service.resource.SubscribeOrderService;
import sunwin.yoms.service.rmiServer.ISubscribeOrder;
import sunwin.yoms.service.security.YomsUserDetails;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.List;

/**
 * Created by watson on 2015/9/12.
 */
@Controller
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private Producer captchaProducer = null;
    @Autowired
    private YoisControllerDefaultData defaultData;
    @Autowired
    private SubscribeOrderService subscribeOrderService;
    @Autowired
    private YomsHelper yomsHelper;

    @RequestMapping(value = R.CheckCode, name = "check", method = RequestMethod.GET)
    public ModelAndView getKaptchaImage(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpSession session = request.getSession();
        String code = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
        Logger.getLogger(this.getClass()).info("验证码： " + code);

        response.setDateHeader("Expires", 0);

        // Set standard HTTP/1.1 no-cache headers.
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");

        // Set IE extended HTTP/1.1 no-cache headers (use addHeader).
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");

        // Set standard HTTP/1.0 no-cache header.
        response.setHeader("Pragma", "no-cache");

        // return a jpeg
        response.setContentType("image/jpeg");

        // create the text for the image
        String capText = captchaProducer.createText();

        // store the text in the session
        session.setAttribute(Constants.KAPTCHA_SESSION_KEY, capText);

        // create the image with the text
        BufferedImage bi = captchaProducer.createImage(capText);
        ServletOutputStream out = response.getOutputStream();

        // write the data out
        ImageIO.write(bi, "jpg", out);
        try {
            out.flush();
        } finally {
            out.close();
        }
        return null;
    }

    /**
     * 用户注册
     *
     * @param
     */
    @RequestMapping(value = R.Register, name = "user/", method = RequestMethod.GET)
    public void RegisterUser() throws YomsException {
    }

    @RequestMapping(value = R.Register, method = RequestMethod.POST)
    public String Register(HttpServletRequest request,
                           ModelMap modelMap,
                           String veryCode,
                           UserDomain userDomain,
                           String repassword) throws YomsException {
        String kaptchaExpected = (String) request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
        if (kaptchaExpected.equals(veryCode)) {
            String str = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$";//必须同时包含字母数字并且是6-20位
            if (userDomain.getUserLoginPassword().matches(str) && userDomain.getUserLoginPassword().equals(repassword)) {
                //密码加密
                String newPwd = BCrypt.hashpw(userDomain.getUserLoginPassword(), BCrypt.gensalt());
                userDomain.setUserLoginPassword(newPwd);
                if (userService.queryUserName(userDomain.getUserLoginName()).size() == 0) {
                    userService.register(userDomain);
                    return "user/login";

                } else {
                    modelMap.addAttribute("error2", "用户名已存在");
                    modelMap.addAttribute("loginName", userDomain.getUserLoginName());
                    return "user/register";
                }
            } else {
                modelMap.addAttribute("error1", "用户密码必须同时包含字母和数字");
                modelMap.addAttribute("loginName", userDomain.getUserLoginName());
                return "user/register";
            }
        } else {
            modelMap.addAttribute("error", "验证码输入有误，请重新输入");
            modelMap.addAttribute("loginName", userDomain.getUserLoginName());
            return "user/register";
        }
    }

    /**
     * 修改密码
     */
    @RequestMapping(value = R.ChangePassword, name = "password/", method = RequestMethod.GET)
    public void changedPassword1(String oldPassword, String newPassword, String rePassword) throws YomsException {

    }

    @RequestMapping(value = R.ChangePassword, method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    @ResponseBody
    public String changedPassword(String oldPassword, String newPassword, String rePassword) throws YomsException {
        YoisAjaxAnswer answer = new YoisAjaxAnswer();
        answer.setSuccess(true);
        //判断密码是否一致
        if (newPassword.equals(rePassword)) {
            YomsUserDetails userDetails = defaultData.getCurrentYimsUserDetails();
            try {
                userService.changePassword(userDetails.getUserid(), oldPassword, newPassword);
            } catch (YomsException e) {
                String errorMsg = e.getMessage();
                answer.setSuccess(false);
                answer.setException(errorMsg);
            }
        } else {
            answer.setSuccess(false);
            answer.setException("密码不一致，请重新输入");
        }
        JSONObject jsonObject = JSONObject.fromObject(answer);
        return jsonObject.toString();
    }

    /**
     * 个人资料访问页
     *
     * @param
     */
    @RequestMapping(value = R.Configuration, name = "user/", method = RequestMethod.GET)
    public void PersonConfig(ModelMap modelMap,
                             @RequestParam(required = false, defaultValue = "1") int tabNum,
                             @RequestParam(required = false, defaultValue = "1") int spix) throws YomsException {
        modelMap.addAttribute("tabNum", tabNum);

        initSubscribeStadium(modelMap, spix);
        initUserDetails(modelMap);
    }

    /**
     * 初始化当前登录用户预约的场馆
     *
     * @param modelMap
     * @param pageIndex
     * @throws YomsException
     */
    private void initSubscribeStadium(ModelMap modelMap, int pageIndex) throws YomsException {
        YomsPage yomsPage = new YomsPage();
        yomsPage.setPageSize(4);
        yomsPage.setPageIndex(pageIndex);
        List<StadiumDomain> stadiumDomains = subscribeOrderService.getSubscribeStadiumsByUid(defaultData.getCurrentYimsUserDetails().getUserid(), yomsPage);
        modelMap.addAttribute("page", yomsPage);
        modelMap.addAttribute("stadiumDomains", stadiumDomains);
    }

    /**
     * 初始化当前登录用户的信息
     *
     * @param modelMap
     * @throws YomsException
     */
    private void initUserDetails(ModelMap modelMap) throws YomsException {
        YomsUserDetails userDetails = defaultData.getCurrentYimsUserDetails();
        UserDomain userdomain = userService.getUserById(userDetails.getUserid());

        modelMap.addAttribute("user", userdomain);
    }


    /**
     * 修改用户昵称
     *
     * @param nickName
     * @throws YomsException
     */
    @RequestMapping(value = R.UpdatePersonInfo, method = RequestMethod.POST, produces = {"text/html;charset=UTF-8"})
    @ResponseBody
    public String PersonConfig(String nickName,
                               ModelMap modelMap,
                               @RequestParam(required = false, defaultValue = "2") int tabNum) throws YomsException {
        modelMap.addAttribute("tabNum", tabNum);

        YomsUserDetails userDetails = defaultData.getCurrentYimsUserDetails();
        UserDomain userDomain = userService.personConfig1(userDetails.getUserid(), nickName);
        modelMap.addAttribute("user", userDomain);
        userDetails.setNickname(userDomain.getUserNickname());

        return "<html><script>window.location.href='" + R.getConfiguration() + "?tabNum=2'</script></html>";
    }

    /**
     * 获取手机验证码
     */
    @RequestMapping(value = R.PhoneCheckNumber, method = RequestMethod.POST, produces = {"text/html;charset=UTF-8"})
    @ResponseBody
    public String getPhoneCheckCode(HttpServletRequest request,
                                    String phoneNumber) throws Exception {
        //验证是不是手机号
        String str = "^\\d+$";
        if (phoneNumber.matches(str)) {
            AllCheckCode(request);
            SendPhoneCheckCode(phoneNumber, request);
            return "success";
        } else {
            return "输入的手机号码不正确";
        }
    }

    /**
     * 绑定手机验证码
     */
    @RequestMapping(value = R.BindPhoneCheck, method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    @ResponseBody
    public String ComparePhoneCode(HttpServletRequest request,
                                   String phoneNumber,
                                   String checkCode) throws YomsException {
        //Important
        YoisAjaxAnswer ajaxAnser = new YoisAjaxAnswer();
        ajaxAnser.setSuccess(true);
        String str = "^\\d+$";
        if (phoneNumber.matches(str)) {
            HttpSession session = request.getSession();
            YomsUserDetails userDetails = defaultData.getCurrentYimsUserDetails();
            String code = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
            Logger.getLogger(this.getClass()).info("用户输入验证码：" + checkCode);
            Logger.getLogger(this.getClass()).info("手机验证码：" + code);
            if (checkCode.equals(code)) {
                try {
                    userService.personConfig2(userDetails.getUserid(), phoneNumber);
                } catch (Exception e) {
                    String phoneError = e.getMessage();
                    ajaxAnser.setException(phoneError);
                    ajaxAnser.setSuccess(false);
                }
            } else {
                ajaxAnser.setSuccess(false);
                ajaxAnser.setException("验证码输入错误");
//                return "验证码输入错误";
            }
        } else {
            ajaxAnser.setSuccess(false);
            ajaxAnser.setException("手机号只能是数字");
//            return "手机号只能是数字";
        }
        //返回捕获的所有异常
        JSONObject jsonObject = JSONObject.fromObject(ajaxAnser);
        return jsonObject.toString();
    }

    /**
     * 获取邮箱验证码
     */
    @RequestMapping(value = R.EmailCheckNumber, method = RequestMethod.POST, produces = {"text/html;charset=UTF-8"})
    @ResponseBody
    public String getEmailCheckCode(HttpServletRequest request, String email) throws Exception {
        String str = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
        if (email.matches(str)) {
            //邮箱验证成功的话--控制台--得到验证码
            AllCheckCode(request);
            //这里发送验证码到邮箱操作
            SendEmailCheckCode(request, email);

            return "success";
        } else {
            throw new YomsException("输入的邮箱不正确");
        }
    }

    /**
     * 绑定邮箱验证码
     */
    @RequestMapping(value = R.BindEmailCheck, method = RequestMethod.POST, name = "emailCheck", produces = "text/html;charset=UTF-8")
    @ResponseBody
    public String CompareEmail(HttpServletRequest request,
                               String email,
                               String checkCode) throws YomsException {
        YoisAjaxAnswer ajaxAnswer = new YoisAjaxAnswer();
        ajaxAnswer.setSuccess(true);
        String str = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
        if (email.matches(str)) {
            YomsUserDetails userDetails = defaultData.getCurrentYimsUserDetails();
            HttpSession session = request.getSession();
            String code = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
            Logger.getLogger(this.getClass()).info("用户输入验证码：" + checkCode);
            Logger.getLogger(this.getClass()).info("邮箱验证码：" + code);
            if (checkCode.equals(code)) {
                try {
                    userService.personConfig3(userDetails.getUserid(), email);
                } catch (Exception e) {
                    String emailError = e.getMessage();
                    ajaxAnswer.setException(emailError);
                    ajaxAnswer.setSuccess(false);
                }
            } else {
                ajaxAnswer.setException("验证码输入错误");
                ajaxAnswer.setSuccess(false);
            }
        } else {
            ajaxAnswer.setException("邮箱格式不正确");
            ajaxAnswer.setSuccess(false);
        }
        JSONObject jsonObject = JSONObject.fromObject(ajaxAnswer);
        return jsonObject.toString();
    }

    /**
     * 生成手机和邮箱验证码
     *
     * @param request
     * @return
     * @throws Exception
     */
    private String AllCheckCode(HttpServletRequest request) throws Exception {
        // create the text for the image
        String capText = captchaProducer.createText();

        // store the text in the session
        HttpSession session = request.getSession();
        session.setAttribute(Constants.KAPTCHA_SESSION_KEY, capText);

        Logger.getLogger(this.getClass()).info("验证码： " + capText);

        return capText;
    }

    /**
     * 发送验证码到手机
     */
    private void SendPhoneCheckCode(String phoneNumber, HttpServletRequest request) throws Exception {
        HttpClient client = new HttpClient();
        PostMethod post = new PostMethod("http://gbk.sms.webchinese.cn");
        post.addRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=gbk");//在头文件中设置转码
        NameValuePair[] data = {new NameValuePair("Uid", "watsonQiu"), new NameValuePair("Key", "d8baddc87b82d5a27052"), new NameValuePair("smsMob", phoneNumber), new NameValuePair("smsText", AllCheckCode(request))};
        post.setRequestBody(data);

        try {
            client.executeMethod(post);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Header[] headers = post.getResponseHeaders();
        int statusCode = post.getStatusCode();
        System.out.println("statusCode:" + statusCode);
        for (Header h : headers) {
            System.out.println(h.toString());
        }
        String result = null;
        try {
            result = new String(post.getResponseBodyAsString().getBytes("gbk"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(result);

        post.releaseConnection();
    }


    /**
     * 发送验证码到邮箱
     */
    private void SendEmailCheckCode(HttpServletRequest request, String emails) {
        //capText验证码变量
        SimpleEmail email = new SimpleEmail();

        try {
            email.setHostName("smtp.163.com");
            try {
                email.addTo(emails);
            } catch (Exception e) {
                e.printStackTrace();
            }
            email.setFrom("sunwin_yoms@163.com", "南京青奥公园交互平台邮箱激活");
            email.setAuthentication("sunwin_yoms", "sunwin2015");
            email.setSubject("邮箱验证码");
            email.setCharset("GB2312");//中文的话,要设置这个属性
            try {
                email.setMsg(AllCheckCode(request));
            } catch (Exception e) {
                e.printStackTrace();
            }
            email.send();
        } catch (EmailException e) {
            e.printStackTrace();
        }
    }
}
